package com.bwie.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.io.file.FileNameUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bwie.config.FreemarkerUtil;
import com.bwie.config.OSSFileUtil;
import com.bwie.mapper.*;
import com.bwie.pojo.*;
import com.bwie.service.TbProjectService;
import com.bwie.utils.R;
import com.bwie.vo.PageInfoVo;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.rabbitmq.client.Channel;
import freemarker.template.TemplateException;
import io.swagger.models.auth.In;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
@Log4j2
public class TbProjectServiceImpl extends ServiceImpl<TbProjectMapper, TbProject> implements TbProjectService {
    @Autowired
    OSSFileUtil ossFileUtil;
    @Autowired
    FastFileStorageClient fastFileStorageClient;
    @Autowired
    TbProjectMapper tbProjectMapper;
    @Autowired
    TbPlusCarMapper tbPlusCarMapper;
    @Autowired
    TbBrandMapper tbBrandMapper;
    @Autowired
    TbAddrMapper tbAddrMapper;
    @Autowired
    RedissonClient redissonClient;
    @Autowired
    TbStatusMapper tbStatusMapper;
    @Autowired
    RabbitTemplate rabbitTemplate;
    @Autowired
    TbProjectService tbProjectService;
    @Autowired
    StringRedisTemplate stringRedisTemplate;

    public R TbBrandById(Integer id) {

        List<TbBrand> tbBrands = tbBrandMapper.selectList(new QueryWrapper<TbBrand>().lambda().eq(TbBrand::getLinkageId, id));

        return R.OK(tbBrands);

    }

    @Override
    @Transactional
    public R saveTbProject(TbProject tbProject) {

        //分布式锁
        RLock lock = redissonClient.getLock("lock" + tbProject);
        //防止重复点击,防止卖超问题
        try {
            boolean b = lock.tryLock(10, 10, TimeUnit.MINUTES);
            if (b) {
                tbProject.setProjectStatus(1);
                tbProject.setProjectNo("JCJH"+new Date().getTime());
                tbProject.setCreateTime(new Date());
                TbPlusCar tbPlusCar = tbPlusCarMapper.selectById(tbProject.getPlusCarId());
                tbProject.setPlusCarName(tbPlusCar.getPlusCarName());
                for (TbAddr tbAddr : tbProject.getAddrList()) {
                    TbAddr addr = tbAddrMapper.selectById(tbAddr.getAddrId());
                    if (tbAddr.getQuantity()>addr.getQuantity()) {
                        return R.ERROR(500,"该"+addr.getAddrName()+"加车数不够了");
                    }
                    addr.setQuantity(addr.getQuantity()-tbAddr.getQuantity());
                    tbAddrMapper.updateById(addr);
                }
                tbProjectMapper.insert(tbProject);
                return R.OK();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
        return R.ERROR(500,"失败");
    }

    @Override
    public R TbPlusCarList() {
        List<TbPlusCar> tbPlusCars = tbPlusCarMapper.selectList(null);
        return R.OK(tbPlusCars);
    }

    @Override
    public R TbAddrList() {
        List<TbAddr> tbAddrs = tbAddrMapper.selectList(null);
        return R.OK(tbAddrs);
    }

    @Override
    public R TbProjectList(PageInfoVo pageInfoVo) {

        Page<TbProject> tbProjectPage=new Page<>(pageInfoVo.getPageNum(),pageInfoVo.getPageSize());

        QueryWrapper<TbProject> tbProjectQueryWrapper=new QueryWrapper<>();
        if (!StringUtils.isEmpty(pageInfoVo.getKeyWord())) {
            tbProjectQueryWrapper.lambda().eq(TbProject::getProjectNo,pageInfoVo.getKeyWord());
        }
        if (pageInfoVo.getStatus()!=null && !pageInfoVo.getStatus().equals(0) ) {
            tbProjectQueryWrapper.lambda().eq(TbProject::getProjectStatus,pageInfoVo.getStatus());
        }
        if (pageInfoVo.getPlusCarId()!=null && pageInfoVo.getPlusCarId()!=0 ) {
            tbProjectQueryWrapper.lambda().eq(TbProject::getPlusCarId,pageInfoVo.getPlusCarId());
        }
        if (pageInfoVo.getBrandId1()!=null&&pageInfoVo.getBrandId1()!=0) {
            tbProjectQueryWrapper.lambda().eq(TbProject::getBrandId1,pageInfoVo.getBrandId1());
        }
        if (pageInfoVo.getBrandId2()!=null&&pageInfoVo.getBrandId2()!=0) {
            tbProjectQueryWrapper.lambda().eq(TbProject::getBrandId2,pageInfoVo.getBrandId2());
        }
        if ( pageInfoVo.getBrandId3()!=null && pageInfoVo.getBrandId3()!=0) {
            tbProjectQueryWrapper.lambda().eq(TbProject::getBrandId3,pageInfoVo.getBrandId3());
        }
        if ( pageInfoVo.getAddrId1()!=null && pageInfoVo.getAddrId1()!=0) {
            tbProjectQueryWrapper.lambda().eq(TbProject::getProjectId,pageInfoVo.getAddrId1());
        }
        if ( pageInfoVo.getAddrId2()!=null && pageInfoVo.getAddrId2()!=0) {
            tbProjectQueryWrapper.lambda().eq(TbProject::getProjectId,pageInfoVo.getAddrId2());
        }

        //按照修改顺序进行倒序展示
        tbProjectQueryWrapper.lambda().orderByDesc(TbProject::getCreateTime);
        Page<TbProject> projectPage = tbProjectMapper.selectPage(tbProjectPage, tbProjectQueryWrapper);
        return R.OK(projectPage);

    }

    @Override
    public R TbStatusList() {
        List<TbStatus> tbStatuses = tbStatusMapper.selectList(null);
        return R.OK(tbStatuses);
    }

    @Override
    public R echoTbProject(Integer id) {
        TbProject tbProject = tbProjectMapper.selectById(id);
        return R.OK(tbProject);
    }

    @Override
    public R updateTbProject(TbProject tbProject) {
        tbProjectMapper.updateById(tbProject);
        return R.OK();
    }

    @Override
    public R examine(Integer id) {
        TbProject tbProject = tbProjectMapper.selectById(id);

        tbProject.setProjectStatus(3);

        //修改状态
        tbProjectMapper.updateById(tbProject);
        //生成消息的唯一id，防止重复消费

        log.info("创建延迟消息,当前时间为{}",new Date());
        rabbitTemplate.convertAndSend("2112a-hsx", "", id, new MessagePostProcessor() {
            @Override
            public Message postProcessMessage(Message message) throws AmqpException {
                message.getMessageProperties().setDelay(10000);
                return message;
            }
        });
        return R.OK();
    }

    @Override
    public R upload(MultipartFile file) {
        try {
            ossFileUtil.uploadFile(file);
            return R.OK();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return R.ERROR(500,"错误");
    }

    @RabbitListener(queues = "211a-hsx-queue")
    public void init(Message message, Channel channel, Integer  id) {
        try {
            TbProject tbProject = tbProjectMapper.selectById(id);
            FreemarkerUtil freemarkerUtil=new FreemarkerUtil();
            freemarkerUtil.createHtml(BeanUtil.beanToMap(tbProject), "project", "D:\\free\\project" + id + ".html");

            log.info("收到消息延迟消息了,当前时间为{},数据为{}",new Date(),tbProject);

            //手动确认消息，防止消息重复消费
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),true);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
